﻿/*
 * Test classes for SSAS Partition Manager 
 * https://ssaspartitionmanager.codeplex.com/
 * 
 * Written by Dr. John Tunnicliffe of Decision Analytics, May 2015
 * eMail: john@decision-analytics.co.uk 
 * http://www.decision-analytics.co.uk/
 * https://www.linkedin.com/in/drjohntunnicliffe
 * 
 * Tests written with FluentAssertions, XUnit and Moq which can be installed from Nuget.  
 * 
 * FluentAssertions
 * http://www.fluentassertions.com/ 
 * 
 * XUnit
 * http://xunit.github.io/
 * 
 * Moq
 * https://github.com/Moq/moq4
 */

namespace AmoExtensions.IntegrationTests
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Dynamic;
    using AmoExtensions;
    using FluentAssertions;
    using Xunit;
    using Moq;
    
    /// <summary>
    /// This class provides the test cube and data for the IntegrationTestPartition class
    /// </summary>
    public class PartitionFixture : IDisposable
    {
        public readonly string SsasDatabaseName;
        public const string SsasCubeName = "Adventure Works";
        public readonly IAmoServer SsasServer;
        
        // define some partition objects which will be used to test the Partition class

        public readonly Partition PartitionExistsAlready;
        public readonly Partition PartitionDoesNotExist;
        public readonly Partition PartitionToCreate;
        public readonly Partition PartitionToDelete;
        public readonly Partition PartitionToProcess;
        public readonly Partition PartitionInMgWithNoTemplate;
        public readonly Partition PartitionWithInvalidDatabase;
        public readonly Partition PartitionWithInvalidCube;
        public readonly Partition PartitionWithInvalidMeasureGroup;
        public readonly Partition PartitionToValidateAndCreate1;
        public readonly Partition PartitionToValidateAndCreate2;
        public readonly Partition PartitionToValidateAndCreate3;

        /// <summary>
        /// As per the xUnit.net mantra, test setup and teardown is done in the constructor and Dispose() methods respectively
        /// </summary>
        public PartitionFixture()
        {
            SsasServer = new AmoServer();
            if (FixtureHelperFunctions.ConnectSsasServer(SsasServer))
            {
                // generate a name and deploy the cube for testing
                SsasDatabaseName = FixtureHelperFunctions.GetUniqueSsasDatabaseName();

                if (FixtureHelperFunctions.DeployTestCube(SsasServer, SsasDatabaseName))
                {
                    // setup fixture data here

                    // Existing partition definition
                    PartitionExistsAlready = new Partition(SsasServer);
                    PartitionExistsAlready.DatabaseName = SsasDatabaseName;
                    PartitionExistsAlready.CubeName = SsasCubeName;
                    PartitionExistsAlready.MeasureGroupName = "Internet Orders";
                    PartitionExistsAlready.PartitionName = "Internet Orders Dev";
                    PartitionExistsAlready.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // partition does not exist
                    PartitionDoesNotExist = new Partition(SsasServer);
                    PartitionDoesNotExist.DatabaseName = SsasDatabaseName;
                    PartitionDoesNotExist.CubeName = SsasCubeName;
                    PartitionDoesNotExist.MeasureGroupName = "Internet Orders";
                    PartitionDoesNotExist.PartitionName = "Does Not Exist";
                    PartitionDoesNotExist.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // delete one of existing the Dev partitions
                    PartitionToDelete = new Partition(SsasServer);
                    PartitionToDelete.DatabaseName = SsasDatabaseName;
                    PartitionToDelete.CubeName = SsasCubeName;
                    PartitionToDelete.MeasureGroupName = "Internet Sales";
                    PartitionToDelete.PartitionName = "Internet Sales Dev";
                    PartitionToDelete.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // process this template partition (won't take long as 1=0)
                    PartitionToProcess = new Partition(SsasServer);
                    PartitionToProcess.DatabaseName = SsasDatabaseName;
                    PartitionToProcess.CubeName = SsasCubeName;
                    PartitionToProcess.MeasureGroupName = "Reseller Orders";
                    PartitionToProcess.PartitionName = "Reseller Orders Template";
                    PartitionToProcess.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // PartitionInMgWithNoTemplate
                    PartitionInMgWithNoTemplate = new Partition(SsasServer);
                    PartitionInMgWithNoTemplate.DatabaseName = SsasDatabaseName;
                    PartitionInMgWithNoTemplate.CubeName = SsasCubeName;
                    PartitionInMgWithNoTemplate.MeasureGroupName = "Sales Targets";
                    PartitionInMgWithNoTemplate.PartitionName = "Sales Targets M1";
                    PartitionInMgWithNoTemplate.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // use this to test for invalid database name
                    PartitionWithInvalidDatabase = new Partition(SsasServer);
                    PartitionWithInvalidDatabase.DatabaseName = "My Missing Database";
                    PartitionWithInvalidDatabase.CubeName = SsasCubeName;
                    PartitionWithInvalidDatabase.MeasureGroupName = "Internet Orders";
                    PartitionWithInvalidDatabase.PartitionName = "Internet Orders Test";
                    PartitionWithInvalidDatabase.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // use this to test for invalid cube name
                    PartitionWithInvalidCube = new Partition(SsasServer);
                    PartitionWithInvalidCube.DatabaseName = SsasDatabaseName;
                    PartitionWithInvalidCube.CubeName = "My Missing Cube";
                    PartitionWithInvalidCube.MeasureGroupName = "Internet Orders";
                    PartitionWithInvalidCube.PartitionName = "Internet Orders Test";
                    PartitionWithInvalidCube.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // use this to test for invalid measure group name
                    PartitionWithInvalidMeasureGroup = new Partition(SsasServer);
                    PartitionWithInvalidMeasureGroup.DatabaseName = SsasDatabaseName;
                    PartitionWithInvalidMeasureGroup.CubeName = SsasCubeName;
                    PartitionWithInvalidMeasureGroup.MeasureGroupName = "My Missing Measure";
                    PartitionWithInvalidMeasureGroup.PartitionName = "Internet Orders Test";
                    PartitionWithInvalidMeasureGroup.PartitionWhereClause = "Fun != 'Integration Testing'";

                    // partition to create
                    PartitionToCreate = new Partition(SsasServer);
                    PartitionToCreate.DatabaseName = SsasDatabaseName;
                    PartitionToCreate.CubeName = SsasCubeName;
                    PartitionToCreate.MeasureGroupName = "Internet Orders";
                    PartitionToCreate.PartitionName = "Created";
                    PartitionToCreate.PartitionWhereClause = "Fun != 'Integration Testing'";
                    PartitionToCreate.PartitionSlice = "[Some].[Fancy].&[MDX]";

                    /*
                     * The definition of the following templates has been changed to test white space between in the WHERE 1=0
                     * Internet Sales Template
                     * Internet Orders Template
                     * Internet Customers Template (has a tab rather than a space)
                     */
                    // partition to validate template
                    PartitionToValidateAndCreate1 = new Partition(SsasServer);
                    PartitionToValidateAndCreate1.DatabaseName = SsasDatabaseName;
                    PartitionToValidateAndCreate1.CubeName = SsasCubeName;
                    PartitionToValidateAndCreate1.MeasureGroupName = "Internet Sales";
                    PartitionToValidateAndCreate1.PartitionName = "Validated and Created";
                    PartitionToValidateAndCreate1.PartitionWhereClause = "Fun != 'Integration Testing'";
                    PartitionToValidateAndCreate1.PartitionSlice = "[Some].[Fancy].&[MDX]";

                    PartitionToValidateAndCreate2 = new Partition(SsasServer);
                    PartitionToValidateAndCreate2.DatabaseName = SsasDatabaseName;
                    PartitionToValidateAndCreate2.CubeName = SsasCubeName;
                    PartitionToValidateAndCreate2.MeasureGroupName = "Internet Orders";
                    PartitionToValidateAndCreate2.PartitionName = "Validated and Created";
                    PartitionToValidateAndCreate2.PartitionWhereClause = "Fun != 'Integration Testing'";
                    PartitionToValidateAndCreate2.PartitionSlice = "[Some].[Fancy].&[MDX]";

                    PartitionToValidateAndCreate3 = new Partition(SsasServer);
                    PartitionToValidateAndCreate3.DatabaseName = SsasDatabaseName;
                    PartitionToValidateAndCreate3.CubeName = SsasCubeName;
                    PartitionToValidateAndCreate3.MeasureGroupName = "Internet Customers";
                    PartitionToValidateAndCreate3.PartitionName = "Validated and Created";
                    PartitionToValidateAndCreate3.PartitionWhereClause = "Fun != 'Integration Testing'";
                    PartitionToValidateAndCreate3.PartitionSlice = "[Some].[Fancy].&[MDX]";
                }
            }
        }

        public void Dispose()
        {
            // drop the test OLAP database  
            SsasServer.DropDatabase(SsasDatabaseName);
            
            // disconnect from the server
            SsasServer.Dispose();
        }
    }
}
